﻿#include "TcpCodec.h"

#include "TcpIOer.h"
#include "RegisterCenter_User.h"
#include "UserRegisterCodec.h"

#include "TcpCodec_HeartBeat.h"
#include "TcpCodec_ReadSensorData.h"
#include "TcpCodec_DataBase.h"
#include "TcpCodec_MCUCtl.h"
#include "TcpCodec_MEMSData.h"
#include "TcpCodec_TurnTable.h"
#include "TcpCodec_User.h"
#include "TcpCodec_Transmit.h"
#include "TcpCodec_Script.h"

TcpCodec::TcpCodec()
{
  setObjectName(getClassNameFirstLow<TcpCodec>());
  codecMap.insert(DataType::HeartBeat,new TcpCodec_HeartBeat());
  codecMap.insert(DataType::ReadSensorData,new TcpCodec_ReadSensorData());
  codecMap.insert(DataType::DataBase,new TcpCodec_DataBase());
  codecMap.insert(DataType::MCUCtrl,new TcpCodec_MCUCtl());
  codecMap.insert(DataType::MEMSData,new TcpCodec_MEMSData());
  codecMap.insert(DataType::TurnTable,new TcpCodec_TurnTable());
  codecMap.insert(DataType::User,new TcpCodec_User());
  codecMap.insert(DataType::Transmit,new TcpCodec_Transmit());;
  codecMap.insert(DataType::Script,new TcpCodec_Script());
}

TcpCodec::~TcpCodec()
{
  for(unsigned char key:codecMap.keys())
    {
      delete codecMap.take(key);
    }
}

void TcpCodec::code(DataPackage_TcpCodec *dataPackage_TcpCodec)
{
  if(Q_NULLPTR==dataPackage_TcpCodec)
    {
      return;
    }
  TcpIOer* tcpIOer=registerCenter_User->getTcpIOerById(dataPackage_TcpCodec->getUserId());
  if(Q_NULLPTR==tcpIOer)
    {
      return;
    }
  tcpIOer->sendData(dataPackage_TcpCodec->getData().prepend(dataPackage_TcpCodec->getPackageType()));
}

void TcpCodec::code(uint userId,uchar type,QByteArray data)
{
  DataPackage_TcpCodec dataPackage_TcpCodec;
  code((&dataPackage_TcpCodec)
       ->setUserId(userId)
       ->setPackageType(type)
       ->setData(data));
}

DataPackage_TcpCodec* TcpCodec::decode(DataPackage_TcpCodec* dataPackageInfo_User)
{
  uchar type=dataPackageInfo_User->getPackageType();
  if(!codecMap.contains(type))
    {
      return Q_NULLPTR;
    }
  return codecMap.value(type)->decode(dataPackageInfo_User);
}

void TcpCodec::slot_decode(TcpIOer * const tcpIOer, QByteArray data)
{
  if(data.isEmpty())
    {
      return;
    }
  DataPackage_TcpCodec* dataPackageInfo_User
      =(new DataPackage_TcpCodec())
      ->setPackageType(data[0])
      ->setData(data.mid(1));
  //-------------拦截器-----------------
  if(dataPackageInfo_User->getPackageType()==DataType::Register)
    {
      DataPackage_UserRegisterCodec* dataPackage_UserRegisterCodec
          =(new DataPackage_UserRegisterCodec())
          ->setTcpIOer(tcpIOer)->setData(dataPackageInfo_User->getData());
      DataPackage_UserRegisterCodec* result=userRegisterCodec->decode(dataPackage_UserRegisterCodec);
      if(Q_NULLPTR!=result)
        {
          tcpIOer->sendData(result->getData().prepend(dataPackageInfo_User->getPackageType()));
        }
      dataPackage_UserRegisterCodec->deleteLater();
    }
  //-----------------------------------
  else
    {
      if(registerCenter_User->isOnline(tcpIOer))
        {
          code(decode(dataPackageInfo_User->setUserId(registerCenter_User->getUserIdByTcpIOer(tcpIOer))));
        }
    }
  dataPackageInfo_User->deleteLater();
}

RegisterCenter_User* TcpCodec::getRegisterCenter_User()const
{
  return registerCenter_User;
}

TcpCodec* TcpCodec::setRegisterCenter_User(RegisterCenter_User* const registerCenter_User)
{
  this->registerCenter_User=registerCenter_User;
  printInjection(this,registerCenter_User);
  return this;
}

UserRegisterCodec* TcpCodec::getUserRegisterCodec()const
{
  return userRegisterCodec;
}

TcpCodec* TcpCodec::setUserRegisterCodec(UserRegisterCodec* const userRegisterCodec)
{
  this->userRegisterCodec=userRegisterCodec;
  printInjection(this,userRegisterCodec);
  return this;
}

void TcpCodec::objectAutoInjection(QHash<QString,QObject*>* objMap)
{
  setRegisterCenter_User(getObjFromMap<RegisterCenter_User>(objMap));
  setUserRegisterCodec(getObjFromMap<UserRegisterCodec>(objMap));
  for(unsigned char key:codecMap.keys())
    {
      ObjAutoInject* temp=dynamic_cast<ObjAutoInject*>(codecMap.value(key));
      if(temp)
        {
          temp->objectAutoInjection(objMap);
        }
    }
}



